import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { CreateMenuDto } from './dto/create-menu.dto';
import { CreateActionDto } from './dto/create-action.dto';
import { Menu } from './entities/menu.entity';
import { Action } from './entities/action.entity';
import { RoleAdmin } from 'src/admin/entities/roleAdmin.entity';
import { Auth } from 'src/role/entities/auth.entity';
import { Role } from 'src/role/entities/role.entity';
import { Repository, In } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { RoleService } from 'src/role/role.service';
@Injectable()
export class MenuService {
  constructor(
      @InjectRepository(Menu)
      private readonly menuRepository: Repository<Menu>,
      @InjectRepository(Action)
      private readonly actionRepository: Repository<Action>,
      @InjectRepository(RoleAdmin)
      private readonly roleAdminRepository: Repository<RoleAdmin>,
      @InjectRepository(Role)
      private readonly roleRepository: Repository<Role>,
      @InjectRepository(Auth)
      private readonly authRepository: Repository<Auth>,
      private readonly roleService: RoleService
      //@Inject(CACHE_MANAGER) private readonly cacheManager: Cache
    ) {}
  async isUserExists(obj){
    const result = await this.menuRepository.findOne({ 
      where: obj
    });
    return !!result
  }

  async save(createMenuDto: CreateMenuDto) {
    const isExists = await this.isUserExists({menuUrl: createMenuDto.menuUrl})
    if(isExists && !createMenuDto.id){
      throw new HttpException('菜单地址不可重复', HttpStatus.INTERNAL_SERVER_ERROR);
    }
    try{
      return await this.menuRepository.save({
        ...createMenuDto,
        icon: createMenuDto.icon ? createMenuDto.icon?.replace(/\s/g, '') : '',
        iconPrefix: 'iconfont'
      })
    } catch (error) {
      throw new HttpException(error.message, error.status, {
        cause: error
      });
    }
  }

  async findAll() {
    try {
      return await this.menuRepository.find({
        select: ['id', 'menuName', 'menuUrl', 'route', 'icon', 'iconPrefix','status', 'sort', 'localFilePath', 'parentId', 'createTime', 'updateTime'],
        order: {
          sort: "ASC"
        }
      });
    } catch (error) {
      throw new HttpException(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
    
  }

  async getMenuListByAuth(adminId) {
    try {

      const { isSuper, roleIds } = await this.roleService.isSuper(adminId)
      // 超管的话查所有菜单
      if(isSuper.length > 0){
        return await this.findAll()
      }
      // 没有的话，查出对应菜单
      // const menus = await this.authRepository.find({ where:{ roleId: In(roleIds), status: 0 } })
      // const mids = menus.map(r => r.menuId)
      // return await this.menuRepository.find({
      //   select: ['id', 'menuName', 'menuUrl', 'route', 'icon', 'iconPrefix', 'status', 'sort', 'localFilePath', 'parentId', 'createTime', 'updateTime'],
      //   where: { id: In(mids) },
      //   order: {
      //     sort: "ASC"
      //   }
      // });
      const menus = await this.menuRepository
      .createQueryBuilder('menu')
      .select([
        'menu.id',
        'menu.menuName',
        'menu.menuUrl',
        'menu.route',
        'menu.icon',
        'menu.iconPrefix',
        'menu.status',
        'menu.sort',
        'menu.localFilePath',
        'menu.parentId',
        'menu.createTime',
        'menu.updateTime'
      ])
      .innerJoin('auth', 'a', 'a.menuId = menu.id AND a.roleId IN (:...roleIds) AND a.status = :status', {
        roleIds,
        status: 0
      })
      .where('menu.status = :menuStatus', { menuStatus: 0 })
      .orderBy('menu.sort', 'ASC')
      .getMany();

      return menus;
    } catch (error) {
      throw new HttpException(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
    
  }

  async getMenuActionList() {
    try {
      return await this.menuRepository.find({
        select: ['id', 'menuName', 'menuUrl', 'route', 'icon', 'iconPrefix', 'status', 'sort', 'localFilePath', 'parentId', 'createTime', 'updateTime'],
        relations:['action'],
        order: {
          sort: "ASC"
        }
      });
    } catch (error) {
      throw new HttpException(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
    
  }
  
  async saveAction(createActionDto: CreateActionDto) {
    try{
      return await this.actionRepository.save({
        ...createActionDto
      })
    } catch (error) {
      throw new HttpException(error.message, error.status, {
        cause: error
      });
    }
  }

  async findActionAll(query) {
    try {
      let queryObj = {
        ...query
      }
      return await this.actionRepository.find({
        select: ['id', 'menuId','actionDom', 'actionName', 'buttonClass', 'buttonType', 'buttonIcon', 'buttonPosition','sort', 'status'],
        order: {
          sort: "ASC"
        },
        where:{ ...queryObj }
      });
    } catch (error) {
      throw new HttpException(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
    
  }

  async delete(id){
    try {
      return await this.menuRepository.delete(id);
    } catch (error) {
      throw new HttpException(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }
}
